home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 3 / Info_Mac_1994-01.iso / Graphics / Utility / GL Viewer 1.1.1 / src ƒ / procImage.c < prev    next >
Text File  |  1993-09-04  |  4KB  |  209 lines

  1. /*
  2.  * Routines to rescale 1-bit deep images by coherent scanline doubling
  3.  * and dithered downsampling.
  4.  *
  5.  * Copyright (c) 1993 by Martin W. Fong
  6.  */
  7.  
  8.  
  9. #include <malloc.h>
  10. #include "glassert.h"
  11. #include "procImage.h"
  12. #include "xlib.h"
  13.  
  14.  
  15. static u_char fDoSmallVideoC = False;
  16.  
  17.  
  18.     void
  19. InitVideoC (u_char fFlag)
  20.  
  21. {
  22.     fDoSmallVideoC = fFlag;
  23. }
  24.  
  25.  
  26.     u_char
  27. FDoSmallVideoC (void)
  28.  
  29. {
  30.     return fDoSmallVideoC;
  31. }
  32.  
  33.  
  34.     u_char *
  35. processVideoC (u_char *ptr, u_long *pDatasize, long *pBpsl, ImageStruct *pIm)
  36.  
  37. {
  38.     if (pIm->w == 640 && pIm->h == 200 && pIm->d == 1)
  39.     {
  40.         u_long    count;
  41.         u_char *p     ;
  42.         int        nColBytes  = pIm->w >> 3;
  43.         int        nColBytes2 = nColBytes << 1;
  44.         u_char *ptr2 = (u_char *) malloc (2L * *pDatasize);
  45.         u_char *p2;
  46.  
  47.  
  48.         assert (ptr2);
  49.  
  50.         /*...Complement the bits...*/
  51.  
  52.         for (count = *pDatasize, p = ptr;
  53.              count /* > 0 */;
  54.              count--, p++)
  55.         {
  56.             register u_char    c = *p;
  57.     
  58.     
  59.             *p = ~c;
  60.         }
  61.  
  62.         /*...Double the image's height by interpolating consecutive scan lines...*/
  63.  
  64.         for (count = pIm->h, p = ptr, p2 = ptr2;
  65.              count /* > 0 */;
  66.              count--, p += nColBytes, p2 += nColBytes2)
  67.         {
  68.             if (count != 1)
  69.             {
  70.                 u_char *p3;
  71.                 short    ithByte;
  72.  
  73.  
  74.                 for (ithByte = 0, p3 = p2 + nColBytes;
  75.                      ithByte < nColBytes;
  76.                      ithByte++, p3++)
  77.                 {
  78.                     *p3 = *(p + ithByte) | *(p + nColBytes + ithByte);
  79.                 }
  80.             }
  81.  
  82.             BlockMove ((Ptr) p, (Ptr) p2, (Size) nColBytes);
  83.         }
  84.  
  85.         free ((char *) ptr);
  86.  
  87.         ptr        = ptr2;
  88.         pIm->h *= 2;
  89.         *pDatasize = *pBpsl * pIm->h;
  90.     }
  91.  
  92.     return ptr;
  93. }
  94.  
  95.  
  96. static u_char bitOnOffs[16] =
  97. {
  98.     0,        /*    0    */
  99.     0,        /*    1    */
  100.     0,        /*    2    */
  101.     2,        /*    3    */
  102.     0,        /*    4    */
  103.     2,        /*    5    */
  104.     2,        /*    6    */
  105.     1,        /*    7    */
  106.     0,        /*    8    */
  107.     2,        /*    9    */
  108.     2,        /*    10    */
  109.     2,        /*    11    */
  110.     1,        /*    12    */
  111.     1,        /*    13    */
  112.     1,        /*    14    */
  113.     1        /*    15    */
  114. };
  115.  
  116.  
  117.     u_char *
  118. shrinkVideoC (u_char *ptr, u_long *pDatasize, long *pBpsl, ImageStruct *pIm)
  119.  
  120. {
  121.     if (pIm->w == 640 && pIm->h == 400 && pIm->d == 1)
  122.     {
  123.         int        nColBytes  = pIm->w >> 3;
  124.         int        nColBytes2 = nColBytes << 1;
  125.         u_char *pNew  = (u_char *) malloc ((size_t) (40L * 200L));
  126.         u_char *pNew2 = pNew;
  127.         u_long    count;
  128.         u_char *p1;
  129.         u_char *p2;
  130.     
  131.     
  132.         assert (pNew);
  133.  
  134.         /*...Downsample two-to-one by examining two consecutive scan lines.
  135.          *     For each pair, use a 2 x 2 bit pattern to compute an output bit.
  136.          *     For 2 x 2 patterns with exactly two bits on, alternate between
  137.          *     off and on to effectively dither consecutive two-bits-on runs.
  138.          */
  139.  
  140.         for (count = pIm->h, p1 = ptr, p2 = ptr + nColBytes;
  141.              count /* > 0 */;
  142.              count -=2, p1 += nColBytes2, p2 += nColBytes2)
  143.         {
  144.             u_char    newByte = 0;
  145.             u_char *p3;
  146.             u_char *p4;
  147.             short    ithByte;
  148.             u_char    fLastOn = 0;
  149.     
  150.     
  151.             for (ithByte = 0, p3 = p1, p4 = p2;
  152.                  ithByte < nColBytes;
  153.                  ithByte++, p3++, p4++)
  154.             {
  155.                 u_char    c1;
  156.                 u_char    c2;
  157.                 u_char    i;
  158.     
  159.     
  160.                 for (i = 0, c1 = *p3, c2 = *p4;
  161.                      i < 4;
  162.                      i++, c1 <<= 2, c2 <<= 2)
  163.                 {
  164.                     register u_char    offset      = ((c1 >> 4) & 0x0C) | ((c2 >> 6) & 0x03);
  165.                     register u_char    bitOnOff = bitOnOffs[offset];
  166.     
  167.     
  168.                     if (bitOnOff & 0x02 /* != 0 */)
  169.                     {
  170.                         bitOnOff  = fLastOn++;
  171.                         fLastOn  &= 0x01;
  172.                     }
  173.                     else
  174.                     {
  175.                         fLastOn = 0;
  176.                     }
  177.     
  178.                     newByte = (newByte << 1) | bitOnOff;
  179.                 }
  180.     
  181.                 if (ithByte & 0x01 /* == 0x01 */)
  182.                 {
  183.                     *pNew2++ = newByte;
  184.                     newByte = 0;
  185.                 }
  186.             }
  187.         }
  188.     
  189.         nColBytes2 = nColBytes >> 1;
  190.     
  191.         for (count = pIm->h, p1 = ptr, pNew2 = pNew;
  192.              count /* > 0 */;
  193.              count -=2, p1 += nColBytes, pNew2 += nColBytes2)
  194.         {
  195.             BlockMove ((Ptr) pNew2, (Ptr) p1, (Size) nColBytes2);
  196.         }
  197.     
  198.         pIm->w       = 320;
  199.         pIm->h       = 200;
  200.         *pBpsl       = (pIm->w + 7) >> 3;
  201.         *pDatasize = *pBpsl * pIm->h;
  202.     
  203.         free ((char *) ptr);
  204.         ptr = pNew;
  205.     }
  206.  
  207.     return ptr;
  208. }
  209.